package models

import (
	"errors"
	"fmt"
	"strconv"

	"github.com/astaxie/beego/orm"
)

const (
	//------------------------------------

	//RoleCreate 增加的权限
	RoleCreate string = "create"
	//RoleRead 获取的权限
	RoleRead string = "read"
	//RoleUpdate 修改的权限
	RoleUpdate string = "update"
	//RoleDelete 删除的权限
	RoleDelete string = "delete"
	//------------------------------------
	//TableUser user
	TableUser string = "t_user"
	//TableApp app
	TableApp string = "t_app"
	// TableLog log
	TableLog string = "t_log"
	// TablePrivilege privilege
	TablePrivilege string = "t_privilege"
	//TableApiUser
	TableApiUser string = "t_api_user"
	//TableApiURL
	TableApiURL string = "t_api_url"
	//TableBasicInfo
	TableBasicInfo string = "t_basic_info"

	//系统提供给聚美内部使用的api
	TableJumeiAPI string = "jumei_api"
)

func LoadAllPrivilege() error {
	privilegeList, _, err := GetAllTPrivilege(nil, nil, nil, nil, 0, 0, false)
	for key, _ := range AllUserPrivilegeList {
		delete(AllUserPrivilegeList, key)
	}
	for _, privilege := range privilegeList {
		var newprivilege TPrivilege
		newprivilege.Action = privilege.Action
		newprivilege.Id = privilege.Id
		newprivilege.TargetRow = privilege.TargetRow
		newprivilege.TargetTable = privilege.TargetTable
		newprivilege.Username = privilege.Username
		AllUserPrivilegeList[privilege.Username] = append(AllUserPrivilegeList[privilege.Username], &newprivilege)
	}
	//-------------加入配置文件中的 权限控制

	return err
}
func GetPrivilegeListByUserID(username string) []*TPrivilege {
	return AllUserPrivilegeList[username]
}

//根据传入的 api 路径，获取在配置文件中 该api所对应的id
func GetJumeiApiIDByPath(method, path string) (result int) {
	for _, jumeiapi := range Conf.JumeiApi.JumeiApiItemList {
		if jumeiapi.Method == method && jumeiapi.Url == path {
			result = jumeiapi.Id
			return
		}
	}
	return
}

//AllUserPrivilegeList 所有用户的所有权限列表。 key 是user的id ，value是该user 拥有的权限
var AllUserPrivilegeList map[string][]*TPrivilege = make(map[string][]*TPrivilege)

//CheckUserPrivilege 检查权限
func CheckUserPrivilege(user *UserWithPirvilege, tablename string, dataRow int, action string) (allowList []int, err error) {
	if user.IsManager == true {
		allowList = []int{0}
		return
	}
	//然后判断普通用户的权限。默认都是无权操作
	err = errors.New("无权操作")
	if user.PrivilegeList == nil {
		return
	}

	for _, privilege := range user.PrivilegeList {
		if privilege.TargetTable == tablename {
			fmt.Println(privilege.Action, action)
			if privilege.Action == action {
				if dataRow == 0 {
					//想拿全部
					if privilege.TargetRow == 0 {
						//权限也是全部
						err = nil
						allowList = []int{0}
						return
					} else {

						err = nil
						allowList = append(allowList, (privilege).TargetRow)
					}
				} else {
					//想拿指定的
					if privilege.TargetRow == 0 {
						err = nil
						allowList = append(allowList, dataRow)
					} else {
						if privilege.TargetRow == dataRow {
							err = nil
							allowList = append(allowList, (privilege).TargetRow)
						}

					}

				}

			}
		}
	}

	return
}

// 对某条数据的全操作权限。
func InsertAllPrivilege(currentUserName, tablename string, dataRow int) ([]*TPrivilege, error) {
	var privilitelist []*TPrivilege
	var read TPrivilege
	read.Action = RoleRead
	read.TargetRow = dataRow
	read.TargetTable = tablename
	read.Username = currentUserName
	privilitelist = append(privilitelist, &read)
	var create TPrivilege
	create.Action = RoleCreate
	create.TargetRow = dataRow
	create.TargetTable = tablename
	create.Username = currentUserName
	privilitelist = append(privilitelist, &create)
	var update TPrivilege
	update.Action = RoleUpdate
	update.TargetRow = dataRow
	update.TargetTable = tablename
	update.Username = currentUserName
	privilitelist = append(privilitelist, &update)
	var deleteitem TPrivilege
	deleteitem.Action = RoleDelete
	deleteitem.TargetRow = dataRow
	deleteitem.TargetTable = tablename
	deleteitem.Username = currentUserName
	privilitelist = append(privilitelist, &deleteitem)
	return privilitelist, BatchInsertPrivilege(privilitelist)
}

func BatchInsertPrivilege(privilitelist []*TPrivilege) (err error) {
	if len(privilitelist) <= 0 {
		return nil
	}
	o := orm.NewOrm()
	insertStr := "insert ignore into " + new(TPrivilege).TableName() + "(action,target_row,target_table,username) values "
	for i, item := range privilitelist {
		insertStr += ("('" + item.Action + "'," + strconv.Itoa(item.TargetRow) + ",'" + item.TargetTable + "','" + item.Username + "')")
		if i < (len(privilitelist) - 1) {
			insertStr += ","
		}
	}
	insertStr += ";"
	_, err = o.Raw(insertStr).Exec()
	return
}
func BatchRemovePrivilege(privilitelist []*TPrivilege) (err error) {
	if len(privilitelist) <= 0 {
		return nil
	}
	o := orm.NewOrm()
	qs := o.QueryTable(new(TPrivilege))
	var deleteids []int64
	for _, item := range privilitelist {
		deleteids = append(deleteids, item.Id)
	}
	_, err = qs.Filter("id__in", deleteids).Delete()
	return
}
func AddPrivilegeToUserPrivilegeList(operator *UserWithPirvilege, newPrivilegelist []*TPrivilege) {

	thisUserRoleList := AllUserPrivilegeList[operator.Username]
	for _, newitem := range newPrivilegelist {
		hasIn := false
	findOld:
		for _, olditem := range thisUserRoleList {
			if newitem.Action == olditem.Action && newitem.TargetRow == olditem.TargetRow && newitem.TargetTable == olditem.TargetTable {
				hasIn = true
				break findOld
			}
		}
		if hasIn == false {
			AllUserPrivilegeList[operator.Username] = append(AllUserPrivilegeList[operator.Username], newitem)
		}
	}
}
func CutPrivilegeToUserPrivilegeList(operator *UserWithPirvilege, cutPrivilegelist []*TPrivilege) {

	thisUserRoleList := AllUserPrivilegeList[operator.Username]
	for i, olditem := range thisUserRoleList {
	findOld:
		for _, newitem := range cutPrivilegelist {
			if newitem.Action == olditem.Action && newitem.TargetRow == olditem.TargetRow && newitem.TargetTable == olditem.TargetTable {
				AllUserPrivilegeList[operator.Username] = append(AllUserPrivilegeList[operator.Username][:i], AllUserPrivilegeList[operator.Username][i+1:]...)
				break findOld
			}
		}
	}
}
